#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;

int count = 10000;

class ThreadData
{
public:
    ThreadData(string &name, pthread_mutex_t *mutex)
        : _name(name), _mutex(mutex)
    {}

public:
    string _name;
    pthread_mutex_t *_mutex;
};
//多线程访问临界资源一定要加锁。
//加锁的力度越小越好。加锁和解锁之间的区域称之为临界区
void *TouchThread(void *arg)
{
    ThreadData *td = (ThreadData *)arg;
    while (1)
    {
        pthread_mutex_lock(td->_mutex); // 加锁
        if (count > 0)
        {
            usleep(1000);
            cout << td->_name << ":" << count << endl;
            --count;
            pthread_mutex_unlock(td->_mutex); // 解锁
            
        }
        else
        {
            pthread_mutex_unlock(td->_mutex); // 解锁
            break;
        }
    }

    delete td;
    return nullptr;
}

int main()
{
    const int NUM = 5;
    pthread_t tid[NUM];
    pthread_mutex_t mutex;            // 互斥量
    pthread_mutex_init(&mutex, NULL); // 初始化互斥量

    // create thread
    for (size_t i = 0; i < NUM; ++i)
    {
        string name = "thread";
        name += to_string(i + 1);
        ThreadData *td = new ThreadData(name, &mutex);//线程的信息，需要名字和互斥量
        pthread_create(tid + i, nullptr, TouchThread, (void *)td);
    }

    // join thread
    for (size_t i = 0; i < NUM; ++i)
    {
        pthread_join(tid[i], nullptr);
    }

    pthread_mutex_destroy(&mutex); // 销毁互斥量
    return 0;
}